import json
import sqlite3
import os
from lxml import etree
import requests

#import p_MyHeader


session = requests.session()
headers = {
    'cookie': '登录之后的cookie'
}


def download_img(url_original, folder):
    Retry_Count = 0  # 计数：记录重新尝试下载的次数

    while (True):
        try:
            img_data = session.get(url_original, headers=headers).content
            img_name = url_original.split('/')[-1]
            with open(folder + img_name, "wb") as fp:
                fp.write(img_data)
            break
        except BaseException as e:
            Retry_Count += 1
            if Retry_Count < 3:
                print("第%d次尝试重新下载:%s" % (Retry_Count, url_original))
            else:
                print("尝试重新下载的次数已达上限")
                return -1  # 将来用于数据库的操作

    return 0


if __name__ == "__main__":
    # 数据库连接
    conn = sqlite3.connect('./1_Download_Log.DB')
    cursor = conn.cursor()
    # url模板
    ajax_img = 'https://www.pixiv.net/ajax/illust/%s'
    ajax_img_pl = 'https://www.pixiv.net/ajax/illust/%s/pages?lang=zh'
    star_url = 'https://www.pixiv.net/ajax/user/这里是一串数字，需要在调试模式中找/illusts/bookmarks?tag=&offset=%d&limit=48&rest=show&lang=zh'
    star_total_page = 30  # 要下载前几页的图片？
    # 保存位置
    folder = './14收集/'
    if not os.path.exists(folder):
        os.mkdir(folder)

    for star_cur_page in range(0, star_total_page):
        # 获取收藏夹中的一页数据
        print("正在获取收藏夹列表，页数(%d/%d)"%(star_cur_page+1,star_total_page), end="")
        print(star_url % (star_cur_page * 48), end="")
        page = session.get(star_url % (star_cur_page * 48), headers=headers)  # 48这个单位 是star_url中的limit
        print(" ------成功")
        page.encoding = page.apparent_encoding
        page_text = page.text
        page_json = json.loads(page_text)

        if page_json['error'] is True:
            raise BaseException(page_json['message'])

        works = page_json['body']['works']
        cur_img_index=0
        # 分析出一个图片并下载
        for work in works:
            print("当前所在页：%d/%d,该图片所在位置：%d/%d"%(star_cur_page+1,star_total_page,cur_img_index+1,48))
            temp_pid = work['id']
            # 在数据库中检测本图片是否已被下载
            sql = 'select count(*) from img where pid="%s" and stat = 1;' % temp_pid
            sql_result = cursor.execute(sql)
            for row in sql_result:
                db_check = row[0]
            if db_check == 1:
                print(temp_pid, "已经下载，故忽略")
                cur_img_index+=1
                continue

            # 获取该图片的具体信息
            temp_ajax_img_url = ajax_img % temp_pid
            result = session.get(temp_ajax_img_url, headers=headers).text
            result_json = json.loads(result)

            if result_json['error'] is True:
                log_msg =str(temp_pid)+":"+result_json['message']
                print(log_msg)
                sql = 'insert into log values ("%s",datetime(\'now\',\'localtime\'));' % log_msg;
                cursor.execute(sql)
                conn.commit()
                cur_img_index+=1
                continue

            # 辨别是否是静态图
            if result_json['body']['illustType'] == 0 or result_json['body']['illustType'] == 1:

                # 如果是单张静图
                if result_json['body']['pageCount'] == 1:
                    #print("测试《下载复数图片》时自动忽略单张静态图", temp_pid)
                    #continue  # 测试下载多张图片时使用
                    print(temp_pid, "可以下载 ",end="")
                    # 解析出下载原图的url
                    url_original = result_json['body']['urls']['original']
                    print(url_original)
                    # 下载原图并保存
                    if download_img(url_original, folder) == 0:
                        print(temp_pid, "下载成功")

                        # 数据库-插入本记录
                        sql = 'insert into img values (%s,%d);' % (temp_pid, 1);  # 1表示下载完成
                        cursor.execute(sql)
                        conn.commit()
                    else:
                        log_msg = str(temp_pid) + "下载失败"
                        print(log_msg)
                        sql = 'insert into log values ("%s",datetime(\'now\',\'localtime\'));' % log_msg;
                        cursor.execute(sql)
                        conn.commit()
                # 如果是多张图片
                elif result_json['body']['pageCount'] > 1:
                    print("复数图片",temp_pid, "可以下载")
                    # 获取图片个数
                    pageCount = result_json['body']['pageCount']
                    # 拼接url，分析每个原图的url
                    temp_img_url_src = ajax_img_pl % temp_pid
                    result_img_pages = session.get(temp_img_url_src, headers=headers).text
                    img_pages_json = json.loads(result_img_pages)
                    if img_pages_json['error'] is True:
                        raise BaseException(img_pages_json['message'])
                    url_originals = []
                    for img_page in img_pages_json['body']:
                        url_originals.append(img_page['urls']['original'])
                    print("复数图片的pid已分析完毕。", url_originals, " ----开始下载")
                    # 准备下载原图
                    temp_img_folder_path = folder + str(temp_pid) + '/'
                    if not os.path.exists(temp_img_folder_path):  # 检测本pid的文件夹是否存在，没有则创建
                        os.mkdir(temp_img_folder_path)
                    # 逐一下载原图
                    success_count = 0  # 用来检测下载的图片数量是否正确
                    for url_original in url_originals:
                        img_name = url_original.split('/')[-1]
                        if not os.path.exists(temp_img_folder_path + img_name):
                            if download_img(url_original, temp_img_folder_path) == 0:
                                success_count += 1
                        else:
                            success_count+=1
                    # 核对下载数量
                    if success_count == pageCount:
                        print("复数图片", temp_pid, "下载完成")
                        sql = 'insert into img values (%s,%d);' % (temp_pid, 1);  # 1表示下载完成
                        cursor.execute(sql)
                        conn.commit()
                    else:
                        log_msg = "复数图片" + str(temp_pid) + "下载数量错误。%d/%d" % (success_count, pageCount)
                        print(log_msg)
                        sql = 'insert into log values ("%s",datetime(\'now\',\'localtime\'));' % log_msg;
                        cursor.execute(sql)
                        conn.commit()

                else:
                    log_msg = str(temp_pid) + "虽是静态图，但不可下载。其页数为:" + str(result_json['body']['pageCount'])
                    print(log_msg)
                    sql = 'insert into log values ("%s",datetime(\'now\',\'localtime\'));' % log_msg;
                    cursor.execute(sql)
                    conn.commit()
            elif result_json['body']['illustType'] == 2:
                log_msg = str(temp_pid) + "为动图，暂时无法下载"
                print(log_msg)
                sql = 'insert into log values ("%s",datetime(\'now\',\'localtime\'));' % log_msg;
                cursor.execute(sql)
                conn.commit()
            else:
                log_msg = str(temp_pid)+"是未知的图片类型，值为"+str(result_json['body']['illustType'])
                print(log_msg)
                sql = 'insert into log values ("%s",datetime(\'now\',\'localtime\'));' % log_msg;
                cursor.execute(sql)
                conn.commit()
            cur_img_index+=1

    print("程序执行完毕")

    # 关闭数据库
    conn.close()
